(defun permutations (items &aux result)
   (if items
       (dolist (item items result)
        (dolist (permutation (permutations (remove item items)))
          (push (cons item permutation) result)))
       '(nil))) 

(defun primep(n)
  (cond 
    ((< n 0) (primep (- n)))
    ((<= n 3) t)
    ((zerop (mod n 2)) nil)
    (t (loop 
	  for i = 3 then (+ 2 i) 
	  with lim = (sqrt n) 
	  when (> i lim) do (return t)
	  when (zerop (mod n i)) do (return nil)))))

(defun digits(n)
  (loop for i = n then (floor (/ i 10))
       while (> i 0)
       collect (mod i 10)))

(defun make-no(digits)
  (if (null digits) 0
      (+ (car digits) (* 10 (make-no (cdr digits))))))

(defun digits-no(n)
  (loop for i = n then (floor (/ i 10))
       while (> i 0)
       count i))

(defun same-digits (a b)
  (let ((digsa (digits a)) (digsb (digits b)))
	(and (= (length digsa) (length digsb))
	  (equal (sort digsa #'>) (sort digsb #'>)))))

(defun distinct-factors (n)
  (loop 
     with nf = n
     with facts = ()
     for i = 2 then  (1+ i)
     when (zerop (mod nf i))
     do (setq facts (cons i facts)) do (loop while (zerop (mod nf i)) do (setq nf (/ nf i)))
     until (= nf 1)
     finally (return facts)))

(defun factors (n)
  (loop 
     with nf = n
     with facts = ()
     for i = 2 then  (1+ i)
     when (zerop (mod nf i))
     do (setq facts (cons i facts)) do (loop while (zerop (mod nf i)) do (setq nf (/ nf i)) do (setq facts (cons i facts)))
     until (= nf 1)
     finally (return facts)))

(defun triangle(n)
  (/ (* n (1+ n)) 2))

(defun square(n)
  (expt n 2))

(defun squarep(x)
  (let ((root (isqrt x)))
    (if (= x (expt root 2)) root nil)))

(defun pentagonal(n)
  (/ (* n (1- (* 3 n))) 2))

(defun hexagonal (n)
  (* n (1- (* 2 n))))

(defun heptagonal (n)
  (/ (* n (- (* 5 n) 3)) 2))

(defun octagonal (n)
  (* n (- (* 3 n) 2)))
